package com.springmvc.platform.util;

import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.regex.Pattern;


/**
 * 对于类的属性、方法操作的工具类
 * 
 * @author wuyanglee on 2016-06-16 下午13:59
 * 
 */
public class BeanUtil {

	/**
	 * get,set方法的最小长度 - 1
	 */
	private static final int SET_START = "set".length();

	/**
	 * is 方法最小长度 - 1
	 */
	private static final int IS_START = "is".length();

	public static final SimpleDateFormat YYYY_MM_DD = new SimpleDateFormat(
			"yyyy-MM-dd");

	/**
	 * 正则表达式校验
	 * 
	 * @author jemi 2016年7月6日
	 */
	public static class Regexp {
		public static final Pattern DIGITS = Pattern.compile("^\\d+$");
		public static final Pattern NUMBER = Pattern
				.compile("^-?(?:\\d+|\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$");

		public static final Pattern COMP_TAX_CODE = Pattern
				.compile("^[0-9a-zA-Z]+$");
		public static final Pattern VEND_TAX_CODE = Pattern
				.compile("^([0-9]|DK|X|L)+$");
		public static final Pattern CIPHER_TEXT = Pattern
				.compile("^[0-9\\+\\-\\*\\/\\<\\>]+$");
	}

	/**
	 * 得到指定的方法
	 * 
	 * @param clz
	 *            方法的类型
	 * @param methodName
	 *            方法的名字
	 * @param paramTypes
	 *            方法的参数列表
	 * @return
	 */
	public static Method getMethod(Class<?> clz, String methodName,
			Class<?>... paramTypes) {
		Method method = null;
		try {
			method = clz.getMethod(methodName, paramTypes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return method;
	}

	/**
	 * getter方法名转换成setter方法名.
	 * 
	 * @param methodName
	 *            getter方法名
	 * @return setter方法名isUserName setUserName
	 */
	public static String getter2Setter(String methodName) {
		if (methodName.startsWith("get")) {
			return "s" + methodName.substring(1);
		} else if (methodName.startsWith("is")) {
			return "set" + methodName.substring(2);
		} else {
			throw new IllegalArgumentException(
					"method not start with get or is.");
		}
	}

	/**
	 * 判断方法名是否符合setter. 1.方法名是3个字符以上 2.方法名以set开头 3.方法只有一个参数 满足这三个条件，就被认为是setter
	 * 
	 * @param method
	 *            方法
	 * @return boolean
	 */
	public static boolean isSetter(Method method) {
		String name = method.getName();
		boolean hasOneParam = method.getParameterTypes().length == 1;
		boolean startsWithGet = (name.length() > SET_START)
				&& name.startsWith("set");

		return startsWithGet && hasOneParam;
	}

	/**
	 * 判断方法名是否符合getter. 1.方法名以get开头，并在3个字符以上 2.方法名以is开头，并在2个字符以上111 3.方法没有参数
	 * 满足这三个条件，就被认为是getter
	 * 
	 * @param method
	 *            方法
	 * @return boolean
	 */
	public static boolean isGetter(Method method) {
		String name = method.getName();
		// 方法没有参数
		boolean hasNoParam = method.getParameterTypes().length == 0;
		// 方法有返回值
		boolean noResultType = method.getReturnType() != void.class;
		// 方法方法名已get开头，大于3位
		boolean startsWithGet = (name.length() > SET_START)
				&& name.startsWith("get");
		// 方法以is开头，大于2位
		boolean startsWithIs = (name.length() > IS_START)
				&& name.startsWith("is");
		// 不是getClass方法
		boolean notGetClass = !name.equals("getClass");

		return hasNoParam && noResultType && notGetClass
				&& (startsWithGet || startsWithIs);
	}

	/**
	 * 比较两个对象是否相等，如果都为空也认为相等
	 */
	public static boolean equals(Object obj1, Object obj2) {
		if ((obj1 == null) && (obj2 == null)) {
			return true;
		}
		if ((obj1 != null) && obj1.equals(obj2)) {
			return true;
		}
		return false;
	}

	/**
	 * 是否为有效数字
	 */
	public static boolean isDigits(Object obj) {
		return Regexp.DIGITS.matcher(toString(obj)).find();
	}

	/**
	 * 是否为公司税号
	 */
	public static boolean isCompanyTaxCode(Object obj) {
		return Regexp.COMP_TAX_CODE.matcher(toString(obj)).find();
	}

	/**
	 * 判断对象是否为空，支持 String, Collection, Map, Object[]
	 */
	public static boolean isEmpty(Object obj) {
		if (obj == null) {
			return true;
		}
		if (obj instanceof String) {
			return ((String) obj).isEmpty();
		}
		if (obj instanceof Collection<?>) {
			return ((Collection<?>) obj).isEmpty();
		}
		if (obj instanceof Map<?, ?>) {
			return ((Map<?, ?>) obj).isEmpty();
		}
		if (obj instanceof Object[]) {
			return ((Object[]) obj).length == 0;
		}
		return false;
	}


	public static Date addDate(Date date, int num) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_MONTH, num);
		return c.getTime();
	}

	public static Date toDate(String dateStr) {
		try {
			return YYYY_MM_DD.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String formatToYYYYMMDD(Date date) {
		try {
			return YYYY_MM_DD.format(date);
		} catch (Exception e) {
			return null;
		}
	}

	public static Date toDate(String dateStr, String pattern) {
		try {
			return new SimpleDateFormat(pattern).parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String formatDate(Date date, String pattern) {
		return new SimpleDateFormat(pattern).format(date);
	}

	public static String leftZeroNumber(int number, int len) {
		return String.format("%0" + len + "d", number);
	}

	public static String toString(Object obj) {
		return toString(obj, null);
	}

	public static String toString(Object obj, String def) {
		return obj == null ? def : obj.toString();
	}

	public static boolean isCiphertext(Object obj) {
		return Regexp.CIPHER_TEXT.matcher(toString(obj)).find();
	}

	/**
	 * 是否数字
	 */
	public static boolean isNumber(Object obj) {
		return Regexp.NUMBER.matcher(toString(obj)).find();
	}
	
	/**
	 * 去两位小数后多余0；如果为空，默认0.00
	 * @param s
	 * @return
	 */
	public static String subZeroAndDot(String s){
		
		if (isEmpty(s)) {
			return "0.00";
		}
		
        if(s.indexOf(".") > 0){  
            s = s.replaceAll("0+?$", "");//去掉多余的0  
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉  
        }
        return s;  
    }
}
